<?php
###
#  Baing PHP 框架 1.0.0
#  http://baing.co/
#
#  Copyright: 白晓阳
#  License: CC BY-NC-SA 4.0
#  https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh
###

namespace bai\feature;


trait Agent
{
    final public static function pick(string|array $path, ?array $source = null)
    {
        static $params = ['$SESSION' => '_SESSION', '$COOKIE' => '_COOKIE'];

        $pieces = is_string($path) ? explode('.', $path) : $path;
        if ($source === null) {
            if ($item = $params[$pieces[0]] ?? '') {
                $item !== '_SESSION' || session_status() === PHP_SESSION_ACTIVE || session_start();
                $source = $GLOBALS[$item];
                array_shift($pieces);
            } else {
                $source = $GLOBALS;
            }
        }

        $data = $source;
        foreach ($pieces as $piece) {
            if (!is_array($data) || !isset($data[$piece])) return null;
            $data = $data[$piece];
        }
        return $data;
    }

    final public static function config(string|array $path)
    {
        return self::pick($path, $GLOBALS['config']);
    }

    final public static function get(?string $key = null)
    {
        if ($key === null) return $_GET;
        return self::access($_GET, $key);
    }

    final public static function post(?string $key = null)
    {
        if ($key === null) return $_POST;
        return self::access($_POST, $key);
    }

    final public static function server(string $key)
    {
        return $_SERVER[strtoupper($key)] ?? null;
    }

    final public static function file(string $key)
    {
        return $_FILES[$key] ?? null;
    }

    final public static function cookie(string|array $key, $value = null)
    {
        return self::access($_COOKIE, $key, $value);
    }

    final public static function session(string|array $key = null, $value = null)
    {
        // TODO: ['read_and_close' => true]
        session_status() === PHP_SESSION_ACTIVE || session_start();
        if ($key === null) return session_id();
        return self::access($_SESSION, $key, $value);
    }

    final public static function removeSession(string|array $key = null)
    {
        session_status() === PHP_SESSION_ACTIVE || session_start();
        self::remove($_SESSION, $key);
    }

    private static function access(array &$source, string|array $key, $value = null)
    {
        if (is_string($key)) {
            if ($value === null) {
                return $source[$key] ?? null;
            }
            $source[$key] = $value;
            return;
        }

        if (isset($key[0])) {
            return array_filter($source, fn($item) => in_array($item, $key), ARRAY_FILTER_USE_KEY);
        }
        foreach ($key as $item => $content) {
            if ($content === null) continue;
            $source[$item] = $content;
        }
    }

    private static function remove(array &$source, string|array|null $key)
    {
        if ($key === null) {
            $source = [];
            return;
        }
        if (is_string($key)) {
            unset($source[$key]);
            return;
        }
        foreach ($key as $item) {
            unset($source[$item]);
        }
    }
}
